const {getDmg,reduceResistanceK,lvSuppressK,objValueAdd } = require("../libs/apis.js")

const WEAPONS = require("./weapons.js");
// https://genshin.honeyhunterworld.com/?lang=CHS
const CLIPDATA_TYPE = {
    max:{
        fixedhp: 298.75,
        fixedAtt: 19.45,
        fixdefence: 23.15,
        reaction : 23.31,
        attRate: 5.83, 
        hpRate: 5.83, 
        criticalRate: 3.89,
        criticalStrike: 7.77,
        defRate: 7.29,
        charging: 6.48
    },
    mid:{
        fixedhp: 253.94,   // 209.13  239   268.88   298.75
        fixdefence: 19.675, // 16.2   18.52  20.83  23.15
        fixedAtt: 16.535,   //  13.62   15.56   17.51  19.45
        reaction : 19.815,  // 16.32   18.65  20.98  23.31
        attRate: 4.955,  // 4.08  4.66  5.25  5.83
        hpRate: 4.955,   // 4.08  4.66  5.25  5.83
        criticalRate: 3.305,   //  2.72  3.11   3.5   3.89
        criticalStrike: 6.605,  //  5.44  6.22  6.99  7.77
        defRate: 6.195,   //  5.1  5.83  6.56   7.29
        charging: 5.505  //  4.53   5.18   5.83   6.48
    }
}

const CLIPDATA = CLIPDATA_TYPE.mid

const CONFIG = {
    chance: 4,
    your_lv: 90,
    enemy_lv: 90,
    clips_main: {
        fixedHp: 4780,
        fixedAtt:311,
        reaction: 187,
        dmgRate: 46.6,
        criticalRate: 31.1,
    },
    clips_initial: [
        ["reaction", "attRate", "criticalRate", "criticalStrike"],
        ["reaction", "attRate", "criticalRate", "criticalStrike"],
        ["charging", "attRate", "criticalRate", "criticalStrike"],
        ["reaction", "attRate", "criticalRate", "criticalStrike"],
        ["charging", "attRate", "reaction", "criticalStrike"]
    ],
    reactionK : 2,
    reactionDmgAdd: 0,
    buffs: [  
        { reaction: 80 + 50*3},  // 饰金
        { dmgRate: 25 , reaction: 200, jk: 30, attRate: 48, jf:30}, // 夜阑 草神250精通 草套jk30 讨龙48
        // { dmgRate: 15, jk: 30},  // 草套
    ]
}

let charaters = {
    units : {
        name: "海参", 
        dmgZhi: 0,
        charging: 100,
        reaction: 0,
        dmgRate: 28.8,
        defRate: 0,
        defence: 781.62, // 653
        weapontype: "sword",
        attRate: 0,
        hp:13348,
        base: 313.32,     // 299.97
        criticalRate: 5,    
        criticalStrike: 50,
        skills: {
            a: [
                function(data){},
            ]
        }
    },
}

let tmp = {}
CONFIG.clips_initial.forEach(item => {
    item.forEach(item2 => {
        if(tmp[item2]) {
            tmp[item2] += 1
        } else {
            tmp[item2] = 1
        }
    })
});
/*
            new: 0.979 1.0032 67.56x2 1.3198 1.6575     z 1.0922
 a 普攻重击倍率 1.1077 1.1236 0.7361 0.7361  1.4529  1.9084    重击 1.4076 * 2 
 e 突刺 草附魔 生成光镜1(当前没光镜生成2) 1.6s光镜攻击一次 光镜最多3个
    lv10 突刺 3.4848攻击2.7878精通   光幕攻击间隔 1.6   光幕持续时间4s 冷却18s  光镜伤害: 1.2096+2.4192
    lv13 突刺 4.114攻击3.2912精通   光幕攻击间隔 1.6   光幕持续时间4s 冷却18s  光镜伤害: 1.428 2.856

 q消耗光镜提高攻击次数 打完后2s根据消耗的光镜生成光镜 (3，2，1，0)  ( 0，1，2，3)
    lv10 2.1888+1.751  4 6 8 10
    lv13 2.584+2.0672  4 6 8 10
 天赋
 重击 下落攻击产生光镜 12s cd
 精通转化 光幕和q增伤 0.1% 最高100

 1 光幕命中敌人-e冷却1s 每s一次
 2 每个光镜提升精通50 4层 200精
 3 e+3
 4 q根据消耗光镜数量产生效果 每消耗1个光镜提升 30点队伍精通 每产生一个光镜10%点海森草伤 持续15s
 5 q+3
 6 q固定产生3个光镜 如果身上已经有3个光镜了 再产生光镜将提高海森10暴击 70爆伤 6s

 海森单人激化综合伤害 只激化无其他拐
 0命 精1专武 557512 精1绿剑517686
 2命 精1专武 647288 精1绿剑580067
 3命 精1专武 736051 精1绿剑670407
 4命 精1专武 841447 精1绿剑766592
 5命 精1专武 852329 精1绿剑778561
 6命 精1专武 1111260 精1绿剑1007909
*/

let cons = 3 // 命座
let chooseIndex = 3; // 查看结果索引
let cid = "units"
let count_kit = 0;
let combination = getCombination(Array(5*CONFIG.chance + 1).fill().map((_,i)=>i), CONFIG.chance, Object.entries(tmp))
let clips_initial_data = calc_clips_initial()
let fs = require("fs")
calc(combination);
function calc(clipSecondData) {
    let charactersDmg = [];
    clipSecondData = clipSecondData.map(clipSecondDataItem => {
        let clipSecond = {}
        clipSecond.des = clipSecondDataItem;
        clipSecond.data = {} 
        for (let secondKey in clipSecond.des) {
            let count =  clipSecond.des[secondKey]
            clipSecond.data[secondKey] = count * CLIPDATA[secondKey]
        }
        return clipSecond
    })
    
    Object.values(WEAPONS).forEach(weapon => {
        if(charaters[cid].weapontype && weapon.weapontype != charaters[cid].weapontype && weapon.weapontype!="all") {return}
        charactersDmg.push(getDMG([charaters[cid],weapon,clips_initial_data,{...CONFIG.clips_main}], clipSecondData, (data,second) => {
            count_kit++;
            data = objValueAdd([data, ...CONFIG.buffs]);
            data.hp = data.hp*(1 + (data.hpRate||0)/100) + data.fixedHp;
            
            
            let eaDmgAdd = data.reaction * 0.1
            if(eaDmgAdd > 100) {eaDmgAdd = 100}
            if(cons >= 4) {
                data.dmgRate += 30
                // data.reaction+=45
            }
            if(cons >= 2) {
                data.reaction += 200
            }
            if(cons >= 6) {
                data.criticalRate += 10
                data.criticalStrike += 70
            }
            if(weapon.skill) { weapon.skill(data); }

            let rea = { reaction:data.reaction, reactionQ:CONFIG.reactionK, reactionDmgAdd:data.reactionDmgAdd || 0 }
            
            let jhDmgZhi = 1447 * 1.25 * (1 + (5*data.reaction)/(data.reaction+1200))
            let tuciRate = [3.4848, 2.7878]
            if(cons >= 3) {
                tuciRate = [4.114, 3.2912]
            }
            let guangmu1 = [1.2096,2.4192]
            if(cons >= 3) {
                guangmu1 = [1.428, 3.856]
            }
            
            let qRate = [2.1888,1.751]
            if(cons >= 5) {
                qRate = [2.584,2.0672]
            }

            let a1Dmg = getDmg({
                data: {
                    ...data,
                    dmgZhi: (data.dmgZhi||0) + (data.aDmgAdd||0),
                    dmgRate: data.dmgRate,
                },
                rate: 0.979
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            let aallDmg = getDmg({
                data: {
                    ...data,
                    dmgZhi: (data.dmgZhi||0) + (data.aDmgAdd||0),
                    dmgRate: data.dmgRate,
                },
                rate: 0.979+1.0032+0.6756*2+ 1.3198 +1.6575
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
           

            let azDmg = getDmg({
                data,
                rate: 1.0922 * 2
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);

            let a1jhDmg = getDmg({
                data: {
                    ...data,
                    dmgZhi: (data.dmgZhi||0) + jhDmgZhi +  (data.aDmgAdd||0),
                    dmgRate: data.dmgRate ,
                },
                rate: 0
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            let azjhDmg = getDmg({
                data: {
                    ...data,
                    dmgZhi: (data.dmgZhi||0) + jhDmgZhi,
                },
                rate: 0
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            let tuciDmgJh = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate ,
                    dmgZhi: (data.dmgZhi||0) + jhDmgZhi +  (data.eDmgAdd||0),
                },
                rate: 0
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            let guangmuDmgJh = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate  + eaDmgAdd,
                    dmgZhi: (data.dmgZhi||0) + jhDmgZhi+  (data.eDmgAdd||0),
                },
                rate: 0
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            let tuciDmg = getDmg({
                data: {
                    ...data,
                    dmgZhi:(data.dmgZhi||0) + data.reaction*tuciRate[1] +  (data.eDmgAdd||0),
                    dmgRate: data.dmgRate,
                },
                rate: tuciRate[0]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            
            let guangmuDmg = getDmg({
                data: {
                    ...data,
                    dmgZhi:(data.dmgZhi||0) + data.reaction*guangmu1[1] +  (data.eDmgAdd||0),
                    dmgRate: data.dmgRate  + eaDmgAdd,
                },
                rate: guangmu1[0]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            
            let qDmgJh = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + eaDmgAdd,
                    dmgZhi: (data.dmgZhi||0) + jhDmgZhi,
                },
                rate: 0
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);
            let qDmg = getDmg({
                data: {
                    ...data,
                    dmgZhi:(data.dmgZhi||0) + data.reaction*qRate[1],
                    dmgRate: data.dmgRate + eaDmgAdd,
                },
                rate: qRate[0]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, data.jf);

            let point = tuciDmg * 1 + guangmuDmg * 3 * 7  + qDmg*4 + (a1Dmg + azDmg) + (aallDmg) * 2.5;
            
            point += a1jhDmg * 5 + azjhDmg + tuciDmgJh + qDmgJh + guangmuDmgJh*6
            let attack = data.base *(1 + data.attRate/100) + data.fixedAtt;
            return {point, data, second, attack, dmg:{tuciDmg,qDmg, guangmuDmg}}
        }))
    })
    
    charactersDmg.sort((a,b)=>{
        return (b.point)-(a.point);
    });
    let sortf = JSON.parse(fs.readFileSync("./sort.js").toString()) 
    let choose = charactersDmg[chooseIndex];
    console.log(choose);
    // fs.writeFileSync("./ret.js", JSON.stringify(choose))

    let name = choose.data.name
    let keys = "_"+choose.data.weaponname+"_6命无拐2+2毕业"
    let sortfData = {key: name+keys, point:choose.point, dmg:JSON.parse(JSON.stringify(choose.dmg))}
    if(sortfData.point && sortfData.point > 0) {
        let org = sortf.findIndex(item3 => item3.key == sortfData.key)
        if(org >= 0){
            sortf[org] = sortfData
        } else {
            sortf.push(sortfData)
        }
        sortf.sort((b,a) => a.point-b.point)
        // fs.writeFileSync("./sort.js", JSON.stringify(sortf))
    }
    console.log(charactersDmg.map((v, n)=>{
        return  `(${n})得分: ${v.data.weaponname} : ${v.point.toFixed(0)}`
    }));
    console.log(count_kit);
}

function getDMG(dataarr, clipSecond, getRet){
    clipSecond = clipSecond.map(second => {
        let panel = objValueAdd([...dataarr, second.data]);
        return  getRet(panel, second)
    })
    clipSecond.sort((b,a)=> a.point-b.point)
    return clipSecond[0]
}

function calc_clips_initial () {
    let clips = CONFIG.clips_initial.map(v => {
        let tmp = {};
        v.forEach(v2 => {
            tmp[v2] = CLIPDATA[v2]
        })
        return tmp
    })
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}
function getCombination (arr, chance, entrys) {
    let num = 5
    var r = [];
    (function f(t, a, n) {
        if (n === 0) {
            if(t.reduce((a1,b1) => a1+b1) !== chance * 5){return}
            let ret = {}
            for (let i in t) {
                if(t[i] > entrys[i][1]*chance){return}
                ret[entrys[i][0]] = t[i]
            }
            r.push(ret)
            return ;
        }
        for (var i = 0, l = a.length; i < l; i++) {
            f(t.concat(a[i]), a, n - 1);
        }
    })([], arr, num);
    return r;
}